package nodeType

import (
	"context"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"tupu-go/controller/node_edge/req_res"
	"tupu-go/model"
	"tupu-go/pkg/database"
)

// NodeTypeService 节点类型服务
type NodeTypeService struct {
	db *gorm.DB
}

// NewNodeTypeService 创建节点类型服务实例
func NewNodeTypeService() *NodeTypeService {
	return &NodeTypeService{
		db: database.GetDB(),
	}
}

// CreateNodeType 创建节点类型
func (s *NodeTypeService) CreateNodeType(ctx context.Context, nodeType req_res.ReqCreateNodeTypeStruct) (*model.NodeType, error) {
	var node model.NodeType
	// 检查类型标识是否已存在
	var count int64
	if err := s.db.WithContext(ctx).Model(&node).
		Where("type_name = ?", nodeType.TypeName).
		Count(&count).Error; err != nil {
		return nil, fmt.Errorf("检查节点类型失败: %w", err)
	}
	if count > 0 {
		return nil, errors.New("节点类型标识已存在")
	}
	node = model.NodeType{
		TypeName:    nodeType.TypeName,
		DisplayName: nodeType.DisplayName,
		Description: nodeType.Description,
	}

	// 创建节点类型
	if err := s.db.WithContext(ctx).Save(&node).Error; err != nil {
		return nil, fmt.Errorf("创建节点类型失败: %w", err)
	}

	return &node, nil
}

// GetNodeType 获取节点类型
func (s *NodeTypeService) GetNodeType(ctx context.Context, nodeTypeID int) (*model.NodeType, error) {
	var nodeType model.NodeType
	if err := s.db.WithContext(ctx).
		Where("node_type_id = ?", nodeTypeID).
		First(&nodeType).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("节点类型不存在")
		}
		return nil, fmt.Errorf("获取节点类型失败: %w", err)
	}
	return &nodeType, nil
}

// ListNodeTypes 分页获取节点类型列表
func (s *NodeTypeService) ListNodeTypes(ctx context.Context, page, pageSize int) ([]model.NodeType, int64, error) {
	var (
		nodeTypes []model.NodeType
		total     int64
	)

	// 统计总数
	if err := s.db.WithContext(ctx).Model(&model.NodeType{}).Count(&total).Error; err != nil {
		return nil, 0, fmt.Errorf("统计节点类型数量失败: %w", err)
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := s.db.WithContext(ctx).
		Offset(offset).
		Limit(pageSize).
		Order("created_at DESC").
		Find(&nodeTypes).Error; err != nil {
		return nil, 0, fmt.Errorf("获取节点类型列表失败: %w", err)
	}

	return nodeTypes, total, nil
}

// UpdateNodeType 更新节点类型
func (s *NodeTypeService) UpdateNodeType(ctx context.Context, nodeTypeID int, nodeType model.NodeType) (model.NodeType, error) {
	// 检查节点类型是否存在
	var existing model.NodeType
	if err := s.db.WithContext(ctx).
		Where("id = ?", nodeTypeID).
		First(&existing).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return existing, errors.New("节点类型不存在")
		}
		return existing, fmt.Errorf("检查节点类型失败: %w", err)
	}

	// 如果修改了类型标识，检查新标识是否已存在
	if nodeType.TypeName != "" && nodeType.TypeName != existing.TypeName {
		var count int64
		if err := s.db.WithContext(ctx).Model(&model.NodeType{}).
			Where("type_name = ? AND id != ?", nodeType.TypeName, nodeTypeID).
			Count(&count).Error; err != nil {
			return existing, fmt.Errorf("检查节点类型标识失败: %w", err)
		}
		if count > 0 {
			return existing, errors.New("新的节点类型标识已存在")
		}
	}

	//// 更新字段（只更新非零值字段）
	//updateData := make(map[string]interface{})
	//if nodeType.TypeName != "" {
	//	updateData["type_name"] = nodeType.TypeName
	//}
	//if nodeType.DisplayName != "" {
	//	updateData["display_name"] = nodeType.DisplayName
	//}
	//if nodeType.Description != "" {
	//	updateData["description"] = nodeType.Description
	//}

	existing = model.NodeType{
		TypeName:    nodeType.TypeName,
		DisplayName: nodeType.DisplayName,
		Description: nodeType.Description,
	}

	if err := s.db.WithContext(ctx).
		Model(&model.NodeType{}).
		Where("id = ?", nodeTypeID).Omit("created_time").
		Updates(&existing).First(&existing).Error; err != nil {
		return existing, fmt.Errorf("更新节点类型失败: %w", err)
	}

	return existing, nil
}

// DeleteNodeType 删除节点类型（级联删除关联数据）
func (s *NodeTypeService) DeleteNodeType(ctx context.Context, nodeTypeID int) (model.NodeType, error) {
	var nodeType model.NodeType

	err := s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 1. 先查询并获取节点类型信息（确保数据存在）
		if err := tx.First(&nodeType, nodeTypeID).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return errors.New("节点类型不存在")
			}
			return fmt.Errorf("查询节点类型失败: %w", err)
		}

		// 2. 级联删除关联的节点属性
		if err := tx.Where("node_type_id = ?", nodeTypeID).Delete(&model.NodeAttribute{}).Error; err != nil {
			return fmt.Errorf("删除关联节点属性失败: %w", err)
		}

		// 3. 删除节点类型（软删除或物理删除）
		if err := tx.Delete(&model.NodeType{}, nodeTypeID).Error; err != nil {
			return fmt.Errorf("删除节点类型失败: %w", err)
		}

		return nil // 事务成功
	})

	if err != nil {
		return model.NodeType{}, err // 事务失败，返回错误
	}

	return nodeType, nil // 返回删除前的节点类型信息
}
